<?php

/*
Plugin to store general metadata for projects 

*/

class ProjectsMetadata{
    
    public $metaDirectoryPath; //full path to the metadata directory
    public $refineURI; //URI for Google Refine. Use the local host, not the reverse proxy for speed
    public $refineHumanURI; //The "human readable/accessible" URI to Google Refine, also used for sending requests to the reverse proxy, not Google refine itself.
    
    public $currentUser; //ID for the current user
    public $projectsMetadata; //projects metadata as stored in the Issue tracker (notes links to issues, documentation status)
    public $curGoogleRefineProjects; //current list of projects reported by Google Refine
    public $unTrackedProjects; //list of untracked projects
    
    public $authHashPrefix; //authorization prefix for interacting with Google Refine reverse proxy server
    
    //if RECORDED by the Google Refine Reverse proxy
    public $issueProject_id; // project ID for the issue tracker to associate a given Google Refine project with issue tracking project
    public $issueUserID; // user ID for the issue tracker a given Google Refine project with issue tracking user
    
    //if NOT recorded by the Google Refine Reverse proxy
    public $fallBack_issueProject_id; // project ID for the issue tracker to associate a given Google Refine project with issue tracking project
    public $fallBack_issueUserID; // user ID for the issue tracker a given Google Refine project with issue tracking user
    public $fallBack_issueProfile_id; // issue tracker profile ID.
    
    
    const projectMetaFileName = "projects"; //name of the file where projects data will be stored
    const directoryType = "metadata"; //location of table metadata, stored as JSON files
    
    
    public function get_gr_projects(){
        
        // Get data from Google Refine to list projects
        $URIsuffix = "/command/core/get-all-project-metadata";
        @$allProjectsJSON = file_get_contents($this->refineURI . $URIsuffix);
        if($allProjectsJSON != false){
                $this->curGoogleRefineProjects = json_decode($allProjectsJSON , true);
        }
        else{
                $this->curGoogleRefineProjects = false;
        }
        
    }
    
    public function get_only_projectsdata(){
        //gets but does not modify projects data.
        $JSONstore = new JSONstore;
        $JSONstore->setDirectory(self::directoryType);
        $projectsMetadata = $JSONstore->read_parse_json(self::projectMetaFileName);
        $this->projectsMetadata = $projectsMetadata;
        return $projectsMetadata;
    }
    
    public function save_projects_metadata(){
        
        $JSONstore = new JSONstore;
        $JSONstore->setDirectory(self::directoryType);
        $json = json_encode($this->projectsMetadata, 1);
        $JSONstore->save_json(self::projectMetaFileName, $json);
        
    }
    
    
    public function update_current_projects(){
        
        //this function provides the current name, last modified information to all projects, it also notes what new projects (datasets) may be in google refine
        
        $projectsMetadata = $this->projectsMetadata;
        $curGoogleRefineProjects = $this->curGoogleRefineProjects;
        $this->unTrackedProjects = false;
        $unTrackedProjects = array();
        $newProjectMetadata = array();
        $storedGRids = array(); //array of GR project IDs already stored in the issue tracker.
        if(is_array($projectsMetadata)){
            foreach($projectsMetadata as $issuesProjectID => $currentProjectDatasets){
                foreach($currentProjectDatasets as $GRprojectID => $projectDataset){
                    
                    if(is_array($curGoogleRefineProjects)){
                        if(array_key_exists($GRprojectID, $curGoogleRefineProjects["projects"])){
                            $projectDataset["name"] = $curGoogleRefineProjects["projects"][$GRprojectID]["name"];
                            $projectDataset["modified"] = $curGoogleRefineProjects["projects"][$GRprojectID]["modified"];
                        }
                    }
                    $newProjectMetadata[$issuesProjectID][$GRprojectID] = $projectDataset;
                    $storedGRids[] = $GRprojectID;
                }
            }
        }
        
        $this->projectsMetadata = $newProjectMetadata;
        
        if(is_array($curGoogleRefineProjects)){
            //if there are projects in Google Refine, check to see if they are not registered in the issue tracker
            
            foreach($curGoogleRefineProjects["projects"] as $GRprojectID => $projectData){
                if(!in_array($GRprojectID,  $storedGRids)){
                    $unTrackedProjects[$GRprojectID] = $projectData;
                }
            }
            if(count($unTrackedProjects)>0){
                $this->unTrackedProjects = $unTrackedProjects;
            }
        }
    }
    
    
 
    function accession_new_gr_project($projectIDkey, $project,  $projectsMetadata){
        
        //accession new GR project into issue tracker, post a new issue about how data edits need to be completed
        
        $GRuserData = $this->get_gr_userData($projectIDkey); //get user data for a project from Google Refine reverse proxy
        
        if(!$GRuserData){
            //no user data available from Google Refine reverse proxy, use the fallbacks instead.
            $this->issueProject_id = $this->fallBack_issueProject_id;
            $this->issueUserID = $this->fallBack_issueUserID;
        }
        
        if($this->issueProject_id == 0){
            $this->issueProject_id = $this->fallBack_issueProject_id;
        }
        
        $GRprojectName = $project["name"];
        $allIssues = array();
        $editIssueNumber = $this->post_refine_issue($projectIDkey, $GRprojectName);
        $allIssues["editIssue"] = $editIssueNumber;
        $allIssues["editResolved"] = false;
        $metadataIssueNumber = $this->post_metadata_issue($projectIDkey, $GRprojectName, $allIssues);
        $allIssues["describeIssue"] = $metadataIssueNumber;
        $allIssues["describeResolved"] = false;
        $fieldsIssue = $this->post_fields_issue($projectIDkey, $GRprojectName, $allIssues);
        $allIssues["fieldsIssue"] = $fieldsIssue;
        $allIssues["fieldsResolved"] = false;
        
        //now create the dataset / project metadata json document
        $TableMetaObj = new TableMetadata;
        $TableMetaObj->issueProject_id = $this->issueProject_id;
        $TableMetaObj->create_dataset_metadata_file($GRuserData, $allIssues, $projectIDkey);
        unset($TableMetaObj);
        
        //now add linking relationship between fields
        //pattern from relationship API: relationship_add( $f_src_bug_id, $f_dest_bug_id, $f_rel_type );       
        relationship_add( $metadataIssueNumber, $fieldsIssue, BUG_RELATED);
        relationship_add( $fieldsIssue, $metadataIssueNumber, BUG_RELATED );
        relationship_add( $fieldsIssue, $editIssueNumber, BUG_RELATED );

        $projectsMetadata[$this->issueProject_id][$projectIDkey] = array(
                                    "originalName" => $GRprojectName,
                                    "created" => $project["created"]
                                    );
        
        return $projectsMetadata;
    }
    
    
    
    
    function get_gr_userData($projectIDkey){
    //HTTP get request to get project user data from the Google Refine reverse proxy server    
        $output = false;
        $authorization = sha1($this->authHashPrefix.$projectIDkey);
        $requestURI = $this->refineHumanURI."/login-check-project?auth=".$authorization."&grProject=".$projectIDkey;
        //echo $requestURI;
        @$json = file_get_contents($requestURI);
        if($json != false){
            $userData = json_decode($json, true);
           
            if(is_array($userData)){
                
                foreach($userData["users"] as $userIDkey => $userDataArray){
                    $this->issueProject_id = $userDataArray["issuesProjectID"];
                    $this->issueUserID = $userIDkey;
                    break;     
                }
                
                $output = array();
                $output = $userData["users"];
            }
        }
        return $output;
    }
    
    
    
    
    //post a new issue to track progress on completing edits in Google Refine.
    function post_refine_issue($GRprojectID, $GRprojectName){
        
        $host = "http://".$_SERVER['SERVER_NAME'];
        $summaryLink = $host."/plugin.php?page=DataRefine/data-doc-summary&grProject=".$GRprojectID;
         
        $summary = "Dataset '".$GRprojectName."' Requires Editing";
       
        $description = "The dataset: '$GRprojectName' (original name) at ".$this->refineHumanURI."/project?project=".$GRprojectID;
        $description .= " may require editing. If you have not already done so, please use Google Refine to review, edit, and clean this dataset. Once completed, indicate below that this issue is 'resolved' or 'closed'. ";
        $description .= " Upon completion of edits and resolution of this issue, you should continue to document this dataset. ";
        $description .= chr(13).chr(13).chr(13);
        $description .= "Summary tracking information for this dataset is at: ".$summaryLink;
        
        $defaultNote = "[Issue automatically reported by the Data Refine Plugin]";
        
        $t_bug_data = new BugData;
	$t_bug_data->category_id = 1;
	$t_bug_data->severity	= 60;
	$t_bug_data->priority	= 60;			
	$t_bug_data->summary	= $summary;
	$t_bug_data->description = $description;
	$t_bug_data->additional_information = $defaultNote;
        $t_bug_data->project_id = $this->issueProject_id;
        $t_bug_data->reporter_id = $this->issueUserID;
        $t_bug_data->profile_id	 = $this->fallBack_issueProfile_id;

        $t_bug_id = $t_bug_data->create();
        
        return $t_bug_id;
    }
    
    
    function post_metadata_issue($GRprojectID, $GRprojectName, $otherIssues){
        
        $host = "http://".$_SERVER['SERVER_NAME'];
        $summaryLink = $host."/plugin.php?page=DataRefine/data-doc-summary&grProject=".$GRprojectID;
        $metadataLink = $host."/plugin.php?page=DataRefine/data-doc-metadata&grProject=".$GRprojectID;
        
        $summary = "Dataset '".$GRprojectName."' Requires Metadata Description";
        
        $description = "The dataset: '$GRprojectName' (original name) at ".$this->refineHumanURI."/project?project=".$GRprojectID;
        $description .= " requires metadata description. ".chr(13).chr(13);
        
        /*
        $description .= "(1) After using Google Refine to review, edit, and clean this dataset, change the status of issue ".$otherIssues["editIssue"]." (";
        $description .= $host."/view.php?id=".$otherIssues["editIssue"].") to 'resolved' or 'closed'. ".chr(13).chr(13).chr(13);
        $description .= "(2) Once all edits are completed for this dataset (and issue ".$otherIssues["editIssue"]." is 'resolved'), ";
        $description .= " the dataset needs descriptive metadata. ";
        */
        
        $description .= "Please provide these metadata using the form at: ";
        $description .= $metadataLink." . Once the form is completed, change the status of this issue to 'resolved' or 'closed'. ";
        
        $description .= chr(13).chr(13).chr(13);
        $description .= "Summary tracking information for this dataset is at: ".$summaryLink;
        
        $defaultNote = "[Issue automatically reported by the Data Refine Plugin]";
        
        $t_bug_data = new BugData;
	$t_bug_data->category_id = 1;
	$t_bug_data->severity	= 60;
	$t_bug_data->priority	= 60;			
	$t_bug_data->summary	= $summary;
	$t_bug_data->description = $description;
	$t_bug_data->additional_information = $defaultNote;
        $t_bug_data->project_id = $this->issueProject_id;
        $t_bug_data->reporter_id = $this->issueUserID;
        $t_bug_data->profile_id	 = $this->fallBack_issueProfile_id;

        $t_bug_id = $t_bug_data->create();
        
        return $t_bug_id;
    }
    
    
    function post_fields_issue($GRprojectID, $GRprojectName, $otherIssues){
        
        $host = "http://".$_SERVER['SERVER_NAME'];
        $summaryLink = $host."/plugin.php?page=DataRefine/data-doc-summary&grProject=".$GRprojectID;
        $metadataLink = $host."/plugin.php?page=DataRefine/data-doc-metadata&grProject=".$GRprojectID;
        $fieldsLink = $host."/plugin.php?page=DataRefine/data-doc-fields&grProject=".$GRprojectID;
        
        $summary = "Dataset '".$GRprojectName."' Requires Field / Column Documentation";
        $description = "The dataset: '$GRprojectName' (original name) at ".$this->refineHumanURI."/project?project=".$GRprojectID;
        $description .= " requires metadata description. ".chr(13).chr(13);
        $description .= "(1) After using Google Refine to review, edit, and clean this dataset, change the status of ";
        $description .= $host."/view.php?id=".$otherIssues["editIssue"]." (issue ".$otherIssues["editIssue"].") to 'resolved' or 'closed'. ".chr(13).chr(13).chr(13);
        $description .= "(2) Please provide these descriptive metadata for this dataset using the form at: ";
        $description .= "(".$metadataLink."). ";
        $description .= "Once the form is completed, change the status of ";
        $description .= $host."/view.php?id=".$otherIssues["describeIssue"]." (issue ".$otherIssues["describeIssue"].") to 'resolved' or 'closed'. ".chr(13).chr(13).chr(13);
        $description .= "(3) The columns (fields) of this dataset require documentation so that they can be understood and used be a larger audience. ";
        $description .= "This documentation will also help link this dataset with other data available on the Web (as in Linked Open Data applications). ";
        $description .= "Use the form at ".$fieldsLink." to document data columns for this dataset. ";
        $description .= "Once the form is completed, change the status of this issue to 'resolved' or 'closed'. ";
        $description .= chr(13).chr(13).chr(13);
        $description .= "Summary tracking information for this dataset is at: ".$summaryLink;
        
        
        $defaultNote = "[Issue automatically reported by the Data Refine Plugin]";
        
        $t_bug_data = new BugData;
	$t_bug_data->category_id = 1;
	$t_bug_data->severity	= 60;
	$t_bug_data->priority	= 60;			
	$t_bug_data->summary	= $summary;
	$t_bug_data->description = $description;
	$t_bug_data->additional_information = $defaultNote;
        $t_bug_data->project_id = $this->issueProject_id;
        $t_bug_data->reporter_id = $this->issueUserID;
        $t_bug_data->profile_id	 = $this->fallBack_issueProfile_id;

        $t_bug_id = $t_bug_data->create();
        
        return $t_bug_id;
    }
    

}//end class

?>